<?php

namespace common\helpers;

use Yii;

/**
 * 日期时间扩展操作函数
 *
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
class DateHelper {

    /**
     * 获取一年内星期列表、每周起始时间
     * @param string $format 日期时间格式
     * @param string $year 年份
     * @return array 一年内的所有星期的起止时间
     */
    public static function getWeeksOfYear($format = "timestamp", $year = null) {
        if ($year == null) {
            $year = date('Y');
        }
        $second_of_day = 24 * 3600;
        $year_start = $year . "-01-01 00:00:00";
        $year_end = $year . "-12-31 23:59:59";
        $startday = strtotime($year_start);
        $first_week_start = $startday;
        $first_week_end = $startday + (7 - date('N', $startday)) * $second_of_day + $second_of_day - 1;
        $week_array[0] = array($first_week_start, $first_week_end);

        $endday = strtotime($year_end);
        $last_week_start = $endday - date('N', $endday) * $second_of_day + 1;
        $last_week_end = $endday;
        $last_week = array($last_week_start, $last_week_end);

        $during = $last_week_start - $first_week_end;

        $during_total_week = intval($during / (7 * $second_of_day));

        for ($i = 0; $i < $during_total_week; $i++) {
            $week_array[$i + 1] = array($first_week_end + (7 * $i * $second_of_day) + 1, $first_week_end + (($i + 1) * $second_of_day * 7));
        }

        $week_array[$during_total_week + 1] = $last_week;

        if ($format != "timestamp") {
            foreach ($week_array as $i => $week) {
                $week_array_of_date_format[$i] = [
                    date($format, $week[0]),
                    date($format, $week[1])
                ];
            }
            return $week_array_of_date_format;
        }

        return $week_array;
    }

    /**
     * 获取时间间隔的区间
     * @param mixed $format 时间戳或者是关键字字符串
     * @param int $duration 时间间隔（单位天）
     * @return array 起止时间数组
     */
    public static function timeInterval($format = "today", $duration = 1) {
        $begintime = false;
        $endtime = false;
        if ($format == 'today') {
            $begintime = strtotime('today');
            $endtime = $begintime + 86400 - 1;
        } elseif ($format == 'tomorrow') {
            $begintime = strtotime('tomorrow');
            $endtime = $begintime + 86400 - 1;
        } elseif ($format == 'weekend') {
            $begintime = strtotime('this week Saturday');
            $endtime = $begintime + 2 * 86400 - 1;
        } elseif ($format == 'week') {
            $begintime = strtotime('this week Monday', time());
            $endtime = $begintime + 7 * 86400 - 1;
        } elseif ($format == 'month') {
            $begintime = strtotime('first day of this month', strtotime('today'));
            $endtime = strtotime('last day of this month', strtotime('tomorrow') - 1);
        } elseif (is_int($format)) {
            $begintime = $format;
            $endtime = $begintime + $duration * 86400 - 1;
        }

        if ($begintime === false || $endtime === false) {
            return false;
        }

        return compact('begintime', 'endtime');
    }

    /**
     * 把秒数转换为时分秒的格式
     * @param Int $times 时间，单位 秒
     * @return String
     */
    public static function toDuration($times) {
        $result = '00:00:00';
        if ($times > 0) {
            $hour = floor($times / 3600);
            $minute = floor(($times - 3600 * $hour) / 60);
            $second = floor((($times - 3600 * $hour) - 60 * $minute) % 60);
            $result = sprintf('%02d:%02d:%02d', $hour, $minute, $second);
        }
        return $result;
    }

    /**
     * 根据生日中的月份和日期来计算所属星座
     *
     * @param int $birth_month
     * @param int $birth_date
     * @return string
     */
    public static function getConstellation($birthday) {
        //判断的时候，为避免出现1和true的疑惑，或是判断语句始终为真的问题，这里统一处理成字符串形式
        $time = strtotime($birthday);
        $date = date('m-d', $time);

        $birth_month = strval($birth_month);
        $constellation_name = [
            '水瓶座', '双鱼座', '白羊座', '金牛座', '双子座', '巨蟹座',
            '狮子座', '处女座', '天秤座', '天蝎座)', '射手座', '摩羯座'
        ];
        if ($birth_date <= 22) {
            if ('1' !== $birth_month) {
                $constellation = $constellation_name[$birth_month - 2];
            } else {
                $constellation = $constellation_name[11];
            }
        } else {
            $constellation = $constellation_name[$birth_month - 1];
        }
        return $constellation;
    }

    /**
     * 根据生日中的年份来计算所属生肖
     *
     * @param int $birthday
     * @return string
     */
    public static function getZodiac($birthday, $full = false) {
        $time = strtotime($birthday);
        $year = date('Y', $time);

        //1900年是子鼠年
        $firstYear = 1900;
        $animals = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'];
        $groundBranchs = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];

        $order = ($year - $firstYear) % 12;

        $string = $animals[$order];
        if ($full) {
            $string = $groundBranchs[$order] . $string;
        }
        return $string;
    }

    /**
     * 解析生日的干支、生肖和星座
     */
    public static function birthday($value) {
        $birth = Yii::$app->formatter->asDate($value, 'Y-m-d');
        list($y, $m, $d) = explode('-', $birth);

        $age = date('Y') - $y;

        $constellations = ['摩羯', '水瓶', '双鱼', '白羊', '金牛', '双子', '巨蟹', '狮子', '处女', '天秤', '天蝎', '射手'];
        $zone = [1222, 122, 222, 321, 421, 522, 622, 722, 822, 922, 1022, 1122, 1222];
        if ((100 * $m + $d) >= $zone[0] || (100 * $m + $d) < $zone[1]) {
            $i = 0;
        } else {
            for ($i = 1; $i < 12; $i++) {
                if ((100 * $m + $d) >= $zone[$i] && (100 * $m + $d) < $zone[$i + 1]) {
                    break;
                }
            }
        }
        $constellation = $constellations[$i] . '座';
        $gzdict = [
            ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'],
            ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥']
        ];
        $i = $y - 1900 + 36;
        $era = $gzdict[0][($i % 10)] . $gzdict[1][($i % 12)];
        $sxdict = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'];
        $zodiac = $sxdict[(($y - 4) % 12)];
        return compact('age', 'constellation', 'era', 'zodiac');
    }

    /**
     * 按天生成日期范围数组
     * @param date|integer $start 开始日期
     * @param date|integer $end 结束日期
     * @return array 日期数组
     */
    public static function dateRange($start, $end) {
        $step = 86400;
        if (!is_numeric($start)) {
            $start = strtotime($start);
        }
        if (!is_numeric($end)) {
            $end = strtotime($end);
        }
        if ($start > $end) {
            $step *= -1;
        }
        if (abs($end - $start) <= $step) {
            $temp = date("Y-m-d", $start);
            return [$temp];
        }
        $format = function($value) {
            return date("Y-m-d", $value);
        };
        return array_map($format, range($start, $end, $step));
    }

}
